package cn.stylefeng.guns.modular.system.service;

import cn.stylefeng.guns.core.util.HttpClientUtil;
import cn.stylefeng.guns.core.util.WebUtils;
import cn.stylefeng.guns.core.util.WeixinConfig;
import cn.stylefeng.guns.core.util.XmlUtils;
import com.alibaba.fastjson.JSON;
import com.fasterxml.jackson.core.type.TypeReference;
import net.sf.json.JSONObject;
import org.apache.commons.beanutils.ConvertUtils;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.lang.ArrayUtils;
import org.apache.commons.lang.StringUtils;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.*;

/**
 * @Author: Xiazt
 * @Date: 2019-10-10 14:58
 */
@Service
public class WeChatPayService {



    /**
     * 申请退款URL
     */
    private static final String REFUND_URL = "https://api.mch.weixin.qq.com/secapi/pay/refund";

//    private static final String ApiKey = "baize41ufzOmhP329xAI4kZX87Mht0d3";

    /**
     * prepay_id请求URL
     */

    private static final String PREPAY_ID_REQUEST_URL = "https://api.mch.weixin.qq.com/pay/unifiedorder";


    public  String getParameterMap (HttpServletRequest request,
                                    Double money ,
                                    String appid,
                                    String trade_type,
                                    String mchId,
                                    String openid,
                                    String nonceStr,
                                    String out_trade_no){
        Map<String, Object> parameterMap = new TreeMap<>();
        parameterMap.put("appid", appid);
        parameterMap.put("trade_type", trade_type);
        if("JSAPI".equals(trade_type)){
            parameterMap.put("openid", openid);
        }
        parameterMap.put("mch_id", mchId);
        parameterMap.put("body", "考试报名");

        parameterMap.put("nonce_str", nonceStr);
        parameterMap.put("total_fee", money.intValue());
        parameterMap.put("spbill_create_ip", request.getRemoteAddr());
        parameterMap.put("out_trade_no", out_trade_no);
        parameterMap.put("notify_url", "http://www.baizezaixian.com/guns/api/exam/weChatPay_notify");
        parameterMap.put("sign", generateSign(parameterMap, WeixinConfig.API_KEY));
        return WebUtils.post(PREPAY_ID_REQUEST_URL, XmlUtils.toXml(parameterMap));
    }

    public Map<String, Object> getModelMap (Double money ,
                                            String appid,
                                            String nonceStr,
                                            String out_trade_no,
                                            Map<String, String> resultMap){
        Map<String, Object> modelMap = new TreeMap<>();
        modelMap.put("appId", appid);
        modelMap.put("nonceStr", nonceStr);
        modelMap.put("package", "prepay_id=" + resultMap.get("prepay_id"));
        modelMap.put("signType", "MD5");
        String sign = generateSign(modelMap,WeixinConfig.API_KEY);
        modelMap.put("sign", sign);
        modelMap.put("orderNo", out_trade_no);
        modelMap.put("totalFee", money.intValue());
        modelMap.put("prepay_id", resultMap.get("prepay_id"));
        modelMap.put("mch_id", WeixinConfig.API_KEY);
        System.out.println("modelMap ================================================== " + modelMap);
        return modelMap;
    }

    public  Map<String, String> getParams (HttpServletRequest request, HttpServletResponse response)throws IOException {
        System.out.println("微信支付回调");
        InputStream inStream = request.getInputStream();
        ByteArrayOutputStream outSteam = new ByteArrayOutputStream();
        byte[] buffer = new byte[1024];
        int len = 0;
        while ((len = inStream.read(buffer)) != -1) {
            outSteam.write(buffer, 0, len);
        }
        String resultxml = new String(outSteam.toByteArray(), "utf-8");

        System.out.println("--------------------------:" + resultxml);
        String paramsJson = JSON.toJSONString(resultxml);
        System.out.println("微信回调参数，{}" + paramsJson);
        outSteam.close();
        inStream.close();
        return  XmlUtils.toObject(resultxml, new TypeReference<Map<String, String>>() {});
    }


    /**
     * 生成签名
     *
     * @param parameterMap 参数
     * @return 签名
     */
    public String generateSign(Map<String, ?> parameterMap,String ApiKey) {
        return StringUtils.upperCase(DigestUtils.md5Hex(joinKeyValue(new TreeMap<>(parameterMap), null, "&key=" + ApiKey, "&", true)));
    }


    /**
     * 连接Map键值对
     *
     * @param map              Map
     * @param prefix           前缀
     * @param suffix           后缀
     * @param separator        连接符
     * @param ignoreEmptyValue 忽略空值
     * @param ignoreKeys       忽略Key
     * @return 字符串
     */
    protected String joinKeyValue(Map<String, Object> map, String prefix, String suffix, String separator, boolean ignoreEmptyValue, String... ignoreKeys) {
        List<String> list = new ArrayList<>();
        if (map != null) {
            for (Map.Entry<String, Object> entry : map.entrySet()) {
                String key = entry.getKey();
                String value = ConvertUtils.convert(entry.getValue());
                if (StringUtils.isNotEmpty(key) && !ArrayUtils.contains(ignoreKeys, key) && (!ignoreEmptyValue || StringUtils.isNotEmpty(value))) {
                    list.add(key + "=" + (value != null ? value : ""));
                }
            }
        }
        return (prefix != null ? prefix : "") + StringUtils.join(list, separator) + (suffix != null ? suffix : "");
    }





    /**
     * 获取用户个人信息（UnionID 机制）
     * @param access_token
     * @param openid
     * @return
     */
    public JSONObject getweChatUserInfo (String access_token, String openid){
        String s = HttpClientUtil.doPost("https://api.weixin.qq.com/sns/userinfo?" +
                        "access_token=" + access_token + "&" +
                        "openid=" + openid,
                new HashMap<>(), "");
        return JSONObject.fromObject(s);

    }

    /**
     * 微信HttpClient请求
     * @param url
     * @param json
     * @return
     */
    public JSONObject weChatHttpClient (String url, String json){
        return JSONObject.fromObject(httpClient ( url, json));
    }
    public String httpClient (String url,String json){
        StringBuilder httpUrl = new StringBuilder(url+"?");
        JSONObject jsonObject = JSONObject.fromObject(json);
        Iterator iter = jsonObject.entrySet().iterator();
        while (iter.hasNext()) {
            Map.Entry entry = (Map.Entry) iter.next();
            httpUrl.append(entry.getKey().toString()+"="+entry.getValue().toString()+"&");
        }
        return HttpClientUtil.doPost(httpUrl.toString(),new HashMap<>(), "");
    }

}
